/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package battleshipgame.manager;

import battleshipgame.logic.Battleship;
import battleshipgame.logic.InvalidInputException;
import battleshipgame.logic.Player;
import battleshipgame.logic.Player.TypeHumanOrBot;
import battleshipgame.xml.Board;
import battleshipgame.xml.Boards;
import battleshipgame.xml.Boat;
import battleshipgame.xml.Boats;
import battleshipgame.xml.Location;
import battleshipgame.xml.ObjectFactory;
import battleshipgame.xml.Players;
import battleshipgame.xml.Submarines;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import javax.xml.bind.Validator;

/**
 * Handles xml input files
 * @author dunay
 */
public class XmlHandler {
    public static  String XML_FILE_PATH = "battleship.xml";


    public static void getGameDataFromXml(GameManager gameManager, String filePath) throws InvalidInputException
    {
        String originalPath = XML_FILE_PATH;
        XML_FILE_PATH = filePath;
        getGameDataFromXml(gameManager);
        XML_FILE_PATH = originalPath;
    }
    public static void getGameDataFromXml(GameManager gameManager) throws InvalidInputException
            {
                Submarines submarines = new Submarines();
                int numOfPlayers;
                gameManager.totalPlayers = 0;
                Map<String,Battleship > battleships;


                //~~~~AUTO Generated Code JAXB Code~~~~~~~~~~~
                try {
                    javax.xml.bind.JAXBContext jaxbCtx = javax.xml.bind.JAXBContext.newInstance(submarines.getClass().getPackage().getName());
                    javax.xml.bind.Unmarshaller unmarshaller = jaxbCtx.createUnmarshaller();
                    submarines =  (Submarines)unmarshaller.unmarshal(new java.io.File(XML_FILE_PATH)); //NOI18N
                } catch (javax.xml.bind.JAXBException ex) {
                    // XXXTODO Handle exception
                    java.util.logging.Logger.getLogger("global").log(java.util.logging.Level.SEVERE, null, ex); //NOI18N
                    throw new InvalidInputException("Invalid xml file\t" + ex.getMessage());
                }
                //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

                //Get Players
                //try
                //{
                Iterator playerIter = submarines.getPlayers().getPlayer().iterator();
                 numOfPlayers = submarines.getBoards().getBoard().size();

                //gameManager.initPlayers(numOfPlayers);
                int i = 0;
                while(playerIter.hasNext())
                {
                    battleshipgame.xml.Player player = (battleshipgame.xml.Player)playerIter.next();
                    // TODO: add computer\ human logic
                    //p.getType()
                    Player newPlayer = new Player(player.getName(),  i++, gameManager);
                    if(player.getType().equals("HUMAN"))
                    {
                        newPlayer.setHumanOrBot(TypeHumanOrBot.HUMAN);
                    }
                    else
                    {
                        newPlayer.setHumanOrBot(TypeHumanOrBot.BOT);
                    }
                    
                    gameManager.addPlayer(newPlayer);
                }

                for(i=0; i< gameManager.players.size(); i++)
                {
                    gameManager.players.get(i).initMarkBoards(numOfPlayers, gameManager.players);
                }
                //}
                //catch(Exception e)
                //{
                //
                //    throw new InvalidInputException("Invalid Player List:\t" + e.getMessage());
                //}

                //Get Battleships
                //try
                //{
                Iterator battleShipIter = submarines.getBoats().getBoat().iterator();
                battleships = new HashMap<String,Battleship >();
                while(battleShipIter.hasNext())
                {
                    battleshipgame.xml.Boat boat = (battleshipgame.xml.Boat) battleShipIter.next();
                    battleships.put(boat.getName(), new Battleship(boat.getName(), (int)boat.getSize()));
                }
                //}
                //catch(Exception e)
                //{
                //    throw new InvalidInputException("Invalid Battleships List");
                //}

                //Add Battlships to Player
                boolean playerFound = false;
                for (i=0; i<numOfPlayers; i++)
                {
                    Player currentPlayer = gameManager.getPlayer(i);
                    //match board to user
                    Iterator boardIter = submarines.getBoards().getBoard().iterator();
                     while(boardIter.hasNext())
                    {
                         battleshipgame.xml.Board board = (battleshipgame.xml.Board) boardIter.next();
                         if(board.getPlayer().equals(gameManager.getPlayer(i).getName() ) )
                         {
                             playerFound = true;
                             //match battleship to user
                             Iterator locationIter = board.getLocation().iterator();
                             currentPlayer.initBattleshipList(board.getLocation().size());
                             while(locationIter.hasNext())
                             {
                                 Location location = (Location)locationIter.next();
                                 Battleship battleship = battleships.get(location.getName());
                                 Player.Direction direction = Player.Direction.valueOf(location.getDirection());
                                 String position = location.getPosition();
                                 //put battleship in board
                                 //Battleship logicBattleship = new Battleship(battleship, battleship.getSize());

                                 //@shaked create copy of  battleship
                                Battleship newBattleship = new Battleship(battleship.getName() , battleship.getSize());
                                currentPlayer.SetBattleshipInBoard(battleship, position, direction);
                             }
                        }
                    }
                }
                }


    public static void saveGameDataToXml(GameManager gameManager, String filePath)
    {
        String originalPath = XML_FILE_PATH;
        XML_FILE_PATH = filePath;
        saveGameDataToXml(gameManager);
        XML_FILE_PATH = originalPath;
    }
    
    public static void saveGameDataToXml(GameManager gameManager) 
            {
                int NUM_OF_BATTLESHIPS = 5;

                Submarines submarines = new Submarines();
                ObjectFactory objFactory = new ObjectFactory();
                Boards xmlBoards = objFactory.createBoards();
                Boats xmlBoats = objFactory.createBoats();
                Players xmlPlayers = objFactory.createPlayers();

                // adds boats
               for(int i=0; i< NUM_OF_BATTLESHIPS; i++)
                {
                        Player firstPlayer = gameManager.getPlayer(0);
                        Boat xmlBoat = objFactory.createBoat();
                        Battleship battleship =  firstPlayer.getBattleShip(i);
                        xmlBoat.setName(battleship.getName());
                        xmlBoat.setSize(battleship.getSize());
                        xmlBoats.getBoat().add(xmlBoat);
                }

                // add players
                for(int i=0; i<gameManager.players.size(); i++)
                {
                    Player player = gameManager.getPlayer(i);
                    
                    battleshipgame.xml.Player xmlPlayer = objFactory.createPlayer();
                    xmlPlayer.setName(player.getName());
                    
                    if (player.getHumanOrBot() == TypeHumanOrBot.BOT)
                    {
                        xmlPlayer.setType("COMPUTER");
                    }
                    else
                    {
                        xmlPlayer.setType("HUMAN");
                    }
                    xmlPlayers.getPlayer().add(xmlPlayer);
                }

                // add boards
                for(int i=0; i<gameManager.players.size(); i++)
                {
                    Player player = gameManager.getPlayer(i);

                    // add board of player
                    Board xmlBoard = objFactory.createBoard();
                    xmlBoard.setPlayer(player.getName());
                    
                    // add locations of boats
                    for(int j=0; j<NUM_OF_BATTLESHIPS; j++)
                    {
                        Location xmlLocation = objFactory.createLocation();
                        Battleship battleship = player.getBattleShip(j);
                        xmlLocation.setPosition(battleship.getCoordinate());
                        xmlLocation.setName(battleship.getName());
                        if( battleship.getDirection() == Player.Direction.HORIZONTAL)
                        {
                            xmlLocation.setDirection("HORIZONTAL");
                        }
                        else
                        {
                            xmlLocation.setDirection("VERTICAL");
                        }
                        xmlBoard.getLocation().add(xmlLocation);
                    }
                    xmlBoards.getBoard().add(xmlBoard);
                    //xmlBoard.getLocation().add

                }

                submarines.setBoards(xmlBoards);
                submarines.setBoats(xmlBoats);
                submarines.setPlayers(xmlPlayers);
                
                //~~~~AUTO Generated Code JAXB Code~~~~~~~~~~~
                try {
                    javax.xml.bind.JAXBContext jaxbCtx = javax.xml.bind.JAXBContext.newInstance(submarines.getClass().getPackage().getName());
                    javax.xml.bind.Marshaller marshaller = jaxbCtx.createMarshaller();
                    marshaller.setProperty(javax.xml.bind.Marshaller.JAXB_ENCODING, "UTF-8"); //NOI18N
                    marshaller.setProperty(javax.xml.bind.Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
                    marshaller.marshal(submarines,new java.io.File(XML_FILE_PATH));
                } catch (javax.xml.bind.JAXBException ex) {
                    // XXXTODO Handle exception
                    java.util.logging.Logger.getLogger("global").log(java.util.logging.Level.SEVERE, null, ex); //NOI18N
                }                
                //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
                 
                
                }


}
